<?php

declare(strict_types=1);

namespace App\AdminApi\Module\Admin\Service;

use App\Common\Model\Admin\DepartmentModel;
use App\Common\Model\Admin\MenuModel;
use App\Common\Query\Query;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Relations\HasOne;
use Zms\AdminElementPlus\FormCreate\Form;
use Zms\AdminElementPlus\FormCreate\FormItem;
use Zms\Basics\BasicsServe;
use Zms\Constants\Database;
use Zms\Exception\AppException;
use Zms\Unit\Arr;

class DepartmentService extends BasicsServe
{
    /**
     * @return MenuModel::class
     */
    public static function model(): string
    {
        return DepartmentModel::class;
    }


    /**
     * 添加后台菜单
     * @param array $values
     * @return null|DepartmentModel
     * @throws AppException
     */
    public function created(array $values): DepartmentModel|false
    {
        if (intval($values['pid']) > 0) {
            /**
             * @var DepartmentModel $parent
             */
            $parent = $this->search(['id' => $values['pid']])->first();
            if (!$parent) {
                throw new AppException('上级菜单不存在,请刷新后重试');
            }
            $values['level'] = $parent['level'] + 1;
            $values['relevance'] = [...$parent->relevance, $parent->id];
        } else {
            $values['level'] = 0;
            $values['relevance'] = [0];
        }
        return parent::created($values);
    }


    /**
     * 获取所选部门的所有部门ID
     * @param array $ids
     * @return array
     */
    public function getSubordinateDepartmentId(array $ids): array
    {
        $depall = [];
        $result = $this->search('id>0')
            ->where(function (Builder $query) use ($ids) {
                Query::FindInSetSearch($query, 'relevance', $ids);
            })
            ->orWhereIn('id', $ids)
            ->select(['id'])
            ->get()
            ->toArray();
        if (count($result) === 0) {
            return $ids;
        }
        return Arr::unique([...$depall, ...array_column($result, 'id')]);
    }


    /**
     * 获取部门显示数据
     */
    public function getDepartmentData(array $where = []): array
    {
        $data = $this->getDepartmentAll($where);
        return Arr::getTree($data);
    }

    /**
     * 获取部门全部数据
     * @param array $where
     * @return array
     */
    private function getDepartmentAll(array $where = []): array
    {
        $all = $this->search()
            ->with(['manage' => function (HasOne $one) {
                $one->select(['id', 'nickname']);
            }])
            ->orderByRaw('sort DESC,id ASC')
            ->get()
            ->toArray();
        foreach ($all as &$item) {
            $item['id'] = (string)$item['id'];
            $item['label'] = $item['name'];
        }
        return $all;
    }

    /**
     * 获取部门完整关系链
     * @param int $id
     * @return array
     */
    public function getArchitectureIds(int $id): array
    {
        $all = $this->search()->orderByRaw('sort DESC,id ASC')->get()->toArray();
        $architecture = [];
        while ($id) {
            foreach ($all as $item) {
                if ($item['id'] === $id) {
                    $architecture[] = $id;
                    $id = $item['pid'];
                }
            }
            if (count($architecture) === 0) {
                break;
            }
        }
        return array_reverse($architecture);
    }


    /**
     * 获取部门数据字典
     */
    public function getTreeFormData(array $where = []): array
    {
        $data = $this->getDepartmentAll($where);
        $news = [];
        foreach ($data as $item) {
            $news[] = [
                'id' => (string)$item['id'],
                'pid' => (string)$item['pid'],
                'name' => $item['name'],
                'label' => $item['name'],
            ];
        }
        return Arr::getTree($news);
    }
}